{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入一些包\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "from sklearn.datasets import make_blobs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "<matplotlib.collections.PathCollection at 0x2168cddf940>"
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 模拟出一些数据集出来\n",
    "# Kmeans算法 随机选取n个点，按照距离分类，再根据分类将点移动到分类的质点，再根据新的点再次分类，再进行下一个循环\n",
    "\n",
    "#r = np.random.randint(1,100)\n",
    "r = 4\n",
    "#print(r)\n",
    "k = 3\n",
    "x , y = make_blobs(n_samples = 300,\n",
    "                   cluster_std = [0.3, 0.3, 0.3],\n",
    "                   centers = [[0,0],[1,1],[-1,1]]\n",
    "                   ,random_state = r\n",
    "                  )\n",
    "sim_data = pd.DataFrame(x, columns = ['x1', 'x2'])\n",
    "sim_data.head(5)\n",
    "\n",
    "datasets = sim_data.copy()\n",
    "\n",
    "plt.scatter(sim_data['x1'], sim_data['x2'])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# 首先随机选出一些中心点出来\n",
    "\n",
    "# 直接用describe的方法将每一列的最小值最大值取出来\n",
    "range_info=datasets.describe().loc[['min','max'],:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "array([-0.66664745])"
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 尝试的使用np.random.uniform的方法来生成随机值\n",
    "range_info['x1']\n",
    "\n",
    "#尝试的使用np.random.uniform的方法来生成随机值 这里是生成了一个\n",
    "# 从x1的最大最小中随机生成1个数\n",
    "np.random.uniform(range_info['x1']['min'],range_info['x1']['max'],1)\n",
    "# 从x2的最大最小中随机生成1个数\n",
    "np.random.uniform(range_info['x2']['min'],range_info['x2']['max'],1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "data": {
      "text/plain": "         x1        x2\n0  1.635198  0.320850\n1 -0.999783  1.702420\n2  1.522052 -0.692503",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>x1</th>\n      <th>x2</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>1.635198</td>\n      <td>0.320850</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>-0.999783</td>\n      <td>1.702420</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>1.522052</td>\n      <td>-0.692503</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l=[]\n",
    "for i in datasets.columns:\n",
    "    l.append(np.random.uniform(range_info[i]['min'],range_info[i]['max'],3))\n",
    "# T转置\n",
    "pd.DataFrame(l,index=datasets.columns).T"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 使用列表解析式写出一个更加有拓展性的代码\n",
    "a=[1,2,3,4,5]\n",
    "\n",
    "[i**2 for i in a]\n",
    "k=3\n",
    "k_randoms= [np.random.uniform(range_info[i]['min']\n",
    "                   ,range_info[i]['max'],k) for i in datasets.columns]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将最后的k_randoms转化成dataframe的格式\n",
    "centers=pd.DataFrame(k_randoms,index=datasets.columns).T\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "         x1        x2\n0 -1.106880 -0.597385\n1  1.040343 -0.558079\n2  0.011417  1.027412",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>x1</th>\n      <th>x2</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>-1.106880</td>\n      <td>-0.597385</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>1.040343</td>\n      <td>-0.558079</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>0.011417</td>\n      <td>1.027412</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 上面的都测试好之后，我们就可以把它写出一个函数\n",
    "def intial_centers(datasets,k=3):\n",
    "    range_info=datasets.describe().loc[['min','max'],:]\n",
    "    k_randoms= [np.random.uniform(range_info[i]['min']\n",
    "                       ,range_info[i]['max'],k) for i in datasets.columns]\n",
    "    centers=pd.DataFrame(k_randoms,index=datasets.columns).T\n",
    "    return centers\n",
    "\n",
    "pqw=intial_centers(datasets)\n",
    "pqw"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "x1   -1.106880\nx2   -0.597385\nName: 0, dtype: float64"
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 取出其中一个质心点，尝试计算每一个点到这个质心点的距离\n",
    "# 可以尝试使用numpy pandas的广播的特性\n",
    "\n",
    "i=0\n",
    "\n",
    "tmp_centers=pqw.loc[i,:]\n",
    "\n",
    "tmp_centers\n",
    "\n",
    "\n",
    "\n",
    "# 对数据集来说，去掉label那一列\n",
    "\n",
    "# 直接使用数据-质心点的方式尝试计算每个点到每个点之间的距离\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 这个是对其中一个质心点来算出每一个点到质心点的距离\n",
    "# 这里有k个质心点，我们也可以尝试使用列表解析来完成\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 当前的d_to_centers是一个list\n",
    "# 里面元素都是每个数据点到第K个点的距离\n",
    "# 我们可以尝试将它转换成dataframe的格式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "#这样子我们的点到质心点的距离都计算好了，可以尝试将它封装成函数\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 这个时候点到每一个质心点的距离就出来了\n",
    "# 需要对每一个点看离哪个质心点最近，从而来更新当前的类别(蔟)\n",
    "# 对于dataframe来说，可以尝试使用idxmin方法\n",
    "# 这样就取出当前每一个样本点最近的质心点\n",
    "# 将当前这个样本点的标签或者类别分给这个最近的质心点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 当每一个点有一个新的蔟的时候，就可以来计算新的质心点的位置了\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 那我们有了这个新的质心点之后，就可以尝试计算新的距离了\n",
    "# 进入下一次迭代"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将上面的单次迭代写出一个函数\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "#创建一个空的SSE_list,用来存SSE的，第一个位置的数为0，无意义，只是方便收敛时最后一个SSE和上一个SSE的对比\n",
    "\n",
    "#初始化质心点\n",
    "\n",
    "#开始迭代\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将所有的代码和函数集合起来\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "from sklearn.datasets import make_blobs\n",
    "\n",
    "def initial_centers(datasets, k = 3):\n",
    "    cols = datasets.columns\n",
    "    data_content = datasets.loc[:, cols != 'label']\n",
    "    range_info = data_content.describe().loc[['min','max']]\n",
    "    k_randoms = [np.random.uniform(range_info[i]['min'], \n",
    "                                   range_info[i]['max'], k) \n",
    "                 for i in range_info.columns]\n",
    "    centers = pd.DataFrame(k_randoms, index = range_info.columns)\n",
    "    return centers.T\n",
    "\n",
    "def cal_distant(dataset, centers):\n",
    "    data = dataset.loc[:, dataset.columns != 'label']\n",
    "    d_to_centers = [np.power(data - centers.loc[i], 2).sum(axis = 1)\n",
    "                    for i in centers.index]\n",
    "    return pd.concat(d_to_centers, axis = 1)\n",
    "\n",
    "def iterate(dataset, centers):\n",
    "    d_to_centers = cal_distant(dataset, centers)\n",
    "    curr_group = d_to_centers.idxmin(axis=1)\n",
    "    SSE = d_to_centers.min(axis = 1).sum()\n",
    "    centers = dataset.loc[:, dataset.columns != 'label'].groupby(curr_group).mean()\n",
    "    return curr_group, SSE, centers\n",
    "\n",
    "def Kmeans_regular(data, k = 3):\n",
    "    SSE_list = [0]\n",
    "    centers = initial_centers(data, k = k)\n",
    "\n",
    "    while True:\n",
    "        curr_group, SSE, centers = iterate(data,centers)\n",
    "        if SSE_list[-1] == SSE:\n",
    "            break\n",
    "        SSE_list.append(SSE)\n",
    "    return curr_group, SSE_list, centers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 检测一下这个代码是否在其它的数据集下可以运行\n",
    "\n",
    "from sklearn.datasets import load_iris\n",
    "data_dict = load_iris()\n",
    "iris = pd.DataFrame(data_dict.data, columns = data_dict.feature_names)\n",
    "iris['label'] = data_dict.target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "curr_group, SSE_list, centers = Kmeans_regular(iris.copy(), k = 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 再重新创建一个数据集\n",
    "\n",
    "X, y = make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)\n",
    "plt.scatter(X[:, 0], X[:, 1]\n",
    "            ,marker='o' #点的形状\n",
    "            ,s=8 #点的大小\n",
    "            #,c=y\n",
    "           )\n",
    "data = pd.DataFrame(X)\n",
    "data['label'] = y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": "<matplotlib.collections.PathCollection at 0x2168d5b7460>"
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "curr_group, SSE_list, centers = Kmeans_regular(data, k = 4)\n",
    "plt.scatter(X[:, 0], X[:, 1]\n",
    "            ,marker='o' #点的形状\n",
    "            ,s=8 #点的大小\n",
    "            ,c=curr_group\n",
    "           )\n",
    "plt.scatter(centers.iloc[:, 0], centers.iloc[:, 1], c = 'red')   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 那这里我们就证明了之前我们写的算法是正确的。\n",
    "# 我们尝试用sklearn的kmeans来实现一遍"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 查看选什么n最好，n从1到10，看一下得出的SSE趋势\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 尝试使用轮廓系数来查看\n",
    "from sklearn.metrics import silhouette_score\n",
    "from sklearn.metrics import silhouette_samples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'y_pred' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mNameError\u001B[0m                                 Traceback (most recent call last)",
      "\u001B[1;32m~\\AppData\\Local\\Temp/ipykernel_14280/3345598492.py\u001B[0m in \u001B[0;36m<module>\u001B[1;34m\u001B[0m\n\u001B[0;32m      1\u001B[0m \u001B[1;31m# 给出所有样本点的轮廓系数的均值\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[1;32m----> 2\u001B[1;33m \u001B[0msilhouette_score\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mX\u001B[0m\u001B[1;33m,\u001B[0m \u001B[0my_pred\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m\u001B[0;32m      3\u001B[0m \u001B[0msilhouette_score\u001B[0m\u001B[1;33m(\u001B[0m\u001B[0mX\u001B[0m\u001B[1;33m,\u001B[0m \u001B[0mcluster\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0mlabels_\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n",
      "\u001B[1;31mNameError\u001B[0m: name 'y_pred' is not defined"
     ]
    }
   ],
   "source": [
    "# 给出所有样本点的轮廓系数的均值\n",
    "silhouette_score(X, y_pred)\n",
    "silhouette_score(X, cluster.labels_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.cluster import KMeans\n",
    "from sklearn.metrics import silhouette_samples, silhouette_score\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.cm as cm\n",
    "import numpy as np\n",
    "\n",
    "#先设定我们要分成的簇数\n",
    "n_clusters = 4\n",
    "\n",
    "#创建一个画布，画布上共有一行两列两个图\n",
    "fig, (ax1, ax2) = plt.subplots(1, 2)\n",
    "\n",
    "#画布尺寸\n",
    "fig.set_size_inches(18, 7)\n",
    "\n",
    "# 第一个图是我们的轮廓系数图像，是由各个簇的轮廓系数组成的横向条形图\n",
    "# 横向条形图的横坐标是我们的轮廓系数取值，纵坐标是我们的每个样本，因为轮廓系数是对于每一个样本进行计算的\n",
    "\n",
    "# 首先我们来设定横坐标\n",
    "# 轮廓系数的取值范围在[-1,1]之间，但我们至少是希望轮廓系数要大于0的\n",
    "# 太长的横坐标不利于我们的可视化，所以只设定X轴的取值在[-0.1,1]之间\n",
    "ax1.set_xlim([-0.1, 1])\n",
    "\n",
    "# 接下来设定纵坐标，通常来说，纵坐标是从0开始，最大值取到X.shape[0]的取值\n",
    "# 但我们希望，每个簇能够排在一起，不同的簇之间能够有一定的空隙\n",
    "# 以便我们看到不同的条形图聚合成的块，理解它是对应了哪一个簇\n",
    "# 因此我们在设定纵坐标的取值范围的时候，在X.shape[0]上，加上一个距离(n_clusters + 1) * 10，留作间隔用\n",
    "ax1.set_ylim([0, X.shape[0] + (n_clusters + 1) * 10])\n",
    "\n",
    "# 开始建模，调用聚类好的标签\n",
    "clusterer = KMeans(n_clusters=n_clusters, random_state=10).fit(X)\n",
    "cluster_labels = clusterer.labels_\n",
    "\n",
    "# 调用轮廓系数分数，注意，silhouette_score生成的是所有样本点的轮廓系数均值\n",
    "# 两个需要输入的参数是，特征矩阵X和聚类完毕后的标签\n",
    "silhouette_avg = silhouette_score(X, cluster_labels)\n",
    "#用print来报一下结果，现在的簇数量下，整体的轮廓系数究竟有多少\n",
    "print(\"For n_clusters =\", n_clusters,\n",
    "      \"The average silhouette_score is :\", silhouette_avg)\n",
    "\n",
    "# 调用silhouette_samples，返回每个样本点的轮廓系数，这就是我们的横坐标\n",
    "sample_silhouette_values = silhouette_samples(X, cluster_labels)\n",
    "\n",
    "#设定y轴上的初始取值\n",
    "y_lower = 10\n",
    "\n",
    "#接下来，对每一个簇进行循环\n",
    "for i in range(n_clusters):\n",
    "    # 从每个样本的轮廓系数结果中抽取出第i个簇的轮廓系数，并对他进行排序\n",
    "    ith_cluster_silhouette_values = sample_silhouette_values[cluster_labels == i]\n",
    "    \n",
    "    #注意, .sort()这个命令会直接改掉原数据的顺序\n",
    "    ith_cluster_silhouette_values.sort()\n",
    "    \n",
    "    #查看这一个簇中究竟有多少个样本\n",
    "    size_cluster_i = ith_cluster_silhouette_values.shape[0]\n",
    "    \n",
    "    #这一个簇在y轴上的取值，应该是由初始值(y_lower)开始，到初始值+加上这个簇中的样本数量结束(y_upper)\n",
    "    y_upper = y_lower + size_cluster_i\n",
    "    \n",
    "    #colormap库中的，使用小数来调用颜色的函数\n",
    "    #在nipy_spectral([输入任意小数来代表一个颜色])\n",
    "    #在这里我们希望每个簇的颜色是不同的，我们需要的颜色种类刚好是循环的个数的种类\n",
    "    #在这里，只要能够确保，每次循环生成的小数是不同的，可以使用任意方式来获取小数\n",
    "    #在这里，我是用i的浮点数除以n_clusters，在不同的i下，自然生成不同的小数\n",
    "    #以确保所有的簇会有不同的颜色\n",
    "    color = cm.nipy_spectral(float(i)/n_clusters)\n",
    "    \n",
    "    #开始填充子图1中的内容\n",
    "    #fill_between是填充曲线与直角之间的空间的函数\n",
    "    #fill_betweenx的直角是在纵坐标上\n",
    "    #fill_betweeny的直角是在横坐标上\n",
    "    #fill_betweenx的参数应该输入(定义曲线的点的横坐标，定义曲线的点的纵坐标，柱状图的颜色)\n",
    "    ax1.fill_betweenx(np.arange(y_lower, y_upper)\n",
    "                      ,ith_cluster_silhouette_values\n",
    "                      ,facecolor=color\n",
    "                      ,alpha=0.7\n",
    "                     )\n",
    "\n",
    "    #为每个簇的轮廓系数写上簇的编号，并且让簇的编号显示坐标轴上每个条形图的中间位置\n",
    "    #text的参数为(要显示编号的位置的横坐标，要显示编号的位置的纵坐标，要显示的编号内容)\n",
    "    ax1.text(-0.05\n",
    "             , y_lower + 0.5 * size_cluster_i\n",
    "             , str(i))\n",
    "\n",
    "    # 为下一个簇计算新的y轴上的初始值，是每一次迭代之后，y的上线再加上10\n",
    "    #以此来保证，不同的簇的图像之间显示有空隙\n",
    "    y_lower = y_upper + 10\n",
    "    \n",
    "#给图1加上标题，横坐标轴，纵坐标轴的标签\n",
    "ax1.set_title(\"The silhouette plot for the various clusters.\")\n",
    "ax1.set_xlabel(\"The silhouette coefficient values\")\n",
    "ax1.set_ylabel(\"Cluster label\")\n",
    "\n",
    "#把整个数据集上的轮廓系数的均值以虚线的形式放入我们的图中\n",
    "ax1.axvline(x=silhouette_avg, color=\"red\", linestyle=\"--\")\n",
    "\n",
    "#让y轴不显示任何刻度\n",
    "ax1.set_yticks([])\n",
    "\n",
    "#让x轴上的刻度显示为我们规定的列表\n",
    "ax1.set_xticks([-0.1, 0, 0.2, 0.4, 0.6, 0.8, 1])\n",
    "\n",
    "#开始对第二个图进行处理，首先获取新颜色，由于这里没有循环，因此我们需要一次性生成多个小数来获取多个颜色\n",
    "colors = cm.nipy_spectral(cluster_labels.astype(float) / n_clusters)\n",
    "\n",
    "ax2.scatter(X[:, 0], X[:, 1]\n",
    "            ,marker='o' #点的形状\n",
    "            ,s=8 #点的大小\n",
    "            ,c=colors\n",
    "           )\n",
    "\n",
    "#把生成的质心放到图像中去\n",
    "centers = clusterer.cluster_centers_\n",
    "# Draw white circles at cluster centers\n",
    "ax2.scatter(centers[:, 0], centers[:, 1], marker='x',\n",
    "            c=\"red\", alpha=1, s=200)\n",
    "\n",
    "#为图二设置标题，横坐标标题，纵坐标标题\n",
    "ax2.set_title(\"The visualization of the clustered data.\")\n",
    "ax2.set_xlabel(\"Feature space for the 1st feature\")\n",
    "ax2.set_ylabel(\"Feature space for the 2nd feature\")\n",
    "\n",
    "#为整个图设置标题\n",
    "plt.suptitle((\"Silhouette analysis for KMeans clustering on sample data \"\n",
    "              \"with n_clusters = %d\" % n_clusters),\n",
    "             fontsize=14, fontweight='bold')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.cluster import KMeans\n",
    "from sklearn.metrics import silhouette_samples, silhouette_score\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.cm as cm\n",
    "import numpy as np\n",
    "\n",
    "for n_clusters in [2,3,4,5,6,7]:\n",
    "    n_clusters = n_clusters\n",
    "    fig, (ax1, ax2) = plt.subplots(1, 2)\n",
    "    fig.set_size_inches(18, 7)\n",
    "    ax1.set_xlim([-0.1, 1])\n",
    "    ax1.set_ylim([0, X.shape[0] + (n_clusters + 1) * 10])\n",
    "    clusterer = KMeans(n_clusters=n_clusters, random_state=10).fit(X)\n",
    "    cluster_labels = clusterer.labels_\n",
    "    silhouette_avg = silhouette_score(X, cluster_labels)\n",
    "    print(\"For n_clusters =\", n_clusters,\n",
    "          \"The average silhouette_score is :\", silhouette_avg)\n",
    "    sample_silhouette_values = silhouette_samples(X, cluster_labels)\n",
    "    y_lower = 10\n",
    "    for i in range(n_clusters):\n",
    "        ith_cluster_silhouette_values = sample_silhouette_values[cluster_labels == i]\n",
    "        ith_cluster_silhouette_values.sort()\n",
    "        size_cluster_i = ith_cluster_silhouette_values.shape[0]\n",
    "        y_upper = y_lower + size_cluster_i\n",
    "        color = cm.nipy_spectral(float(i)/n_clusters)\n",
    "        ax1.fill_betweenx(np.arange(y_lower, y_upper)\n",
    "                          ,ith_cluster_silhouette_values\n",
    "                          ,facecolor=color\n",
    "                          ,alpha=0.7\n",
    "                         )\n",
    "        ax1.text(-0.05\n",
    "                 , y_lower + 0.5 * size_cluster_i\n",
    "                 , str(i))\n",
    "        y_lower = y_upper + 10\n",
    "\n",
    "    ax1.set_title(\"The silhouette plot for the various clusters.\")\n",
    "    ax1.set_xlabel(\"The silhouette coefficient values\")\n",
    "    ax1.set_ylabel(\"Cluster label\")\n",
    "    ax1.axvline(x=silhouette_avg, color=\"red\", linestyle=\"--\")\n",
    "    ax1.set_yticks([])\n",
    "    ax1.set_xticks([-0.1, 0, 0.2, 0.4, 0.6, 0.8, 1])\n",
    "\n",
    "    colors = cm.nipy_spectral(cluster_labels.astype(float) / n_clusters)\n",
    "    ax2.scatter(X[:, 0], X[:, 1]\n",
    "                ,marker='o'\n",
    "                ,s=8\n",
    "                ,c=colors\n",
    "               )\n",
    "    centers = clusterer.cluster_centers_\n",
    "    # Draw white circles at cluster centers\n",
    "    ax2.scatter(centers[:, 0], centers[:, 1], marker='x',\n",
    "                c=\"red\", alpha=1, s=200)\n",
    "    \n",
    "    ax2.set_title(\"The visualization of the clustered data.\")\n",
    "    ax2.set_xlabel(\"Feature space for the 1st feature\")\n",
    "    ax2.set_ylabel(\"Feature space for the 2nd feature\")\n",
    "\n",
    "    plt.suptitle((\"Silhouette analysis for KMeans clustering on sample data \"\n",
    "                  \"with n_clusters = %d\" % n_clusters),\n",
    "                 fontsize=14, fontweight='bold')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 随机初始质心点\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# DBSCAN\n",
    "\n",
    "from sklearn.datasets import make_moons\n",
    "X,y = make_moons(200, noise = 0.05, random_state=0)\n",
    "plt.scatter(X[:,0],X[:,1], c=y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.cluster import KMeans\n",
    "kmeans = KMeans(n_clusters=2)\n",
    "kmeans.fit(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "centers = kmeans.cluster_centers_\n",
    "plt.scatter(X[:,0],X[:,1], c = kmeans.labels_)\n",
    "plt.plot(centers[:,0], centers[:,1],'ro')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 使用DBSCAN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}